home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / src / oct-stream.h < prev    next >
C/C++ Source or Header  |  1997-03-07  |  13KB  |  532 lines

  1. /*
  2.  
  3. Copyright (C) 1996 John W. Eaton
  4.  
  5. This file is part of Octave.
  6.  
  7. Octave is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. Octave is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Octave; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. #if !defined (octave_octave_stream_h)
  24. #define octave_octave_stream_h 1
  25.  
  26. #include <string>
  27.  
  28. #include <iostream.h>
  29. #include <strstream.h>
  30.  
  31. #include "Array.h"
  32. #include "data-conv.h"
  33. #include "mach-info.h"
  34.  
  35. #include "oct-obj.h"
  36. #include "str-vec.h"
  37.  
  38. struct
  39. scanf_format_elt
  40. {
  41.   scanf_format_elt (const char *txt = 0, int w = 0, bool d = false,
  42.             char typ = '\0', char mod = '\0')
  43.     : text (txt), width (w), discard (d), type (typ), modifier (mod) { }
  44.  
  45.   ~scanf_format_elt (void) { delete text; }
  46.  
  47.   const char *text;
  48.   int width;
  49.   bool discard;
  50.   char type;
  51.   char modifier;
  52. };
  53.  
  54. class
  55. scanf_format_list
  56. {
  57. public:
  58.  
  59.   scanf_format_list (const string& fmt = string ());
  60.  
  61.   ~scanf_format_list (void);
  62.  
  63.   int num_conversions (void) { return nconv; }
  64.  
  65.   // The length can be different than the number of conversions.
  66.   // For example, "x %d y %d z" has 2 conversions but the length of
  67.   // the list is 3 because of the characters that appear after the
  68.   // last conversion.
  69.  
  70.   int length (void) { return list.length (); }
  71.  
  72.   const scanf_format_elt *first (void)
  73.     {
  74.       curr_idx = 0;
  75.       return current ();
  76.     }
  77.  
  78.   const scanf_format_elt *current (void) const
  79.     { return list.length () > 0 ? list.elem (curr_idx) : 0; }
  80.  
  81.   const scanf_format_elt *next (void)
  82.     {
  83.       curr_idx++;
  84.       if (curr_idx >= list.length ())
  85.     curr_idx = 0;
  86.       return current ();
  87.     }
  88.  
  89.   void printme (void) const;
  90.  
  91.   bool ok (void) const { return (nconv >= 0); }
  92.  
  93.   operator void* () const { return ok () ? (void *) -1 : (void *) 0; }
  94.  
  95.   bool all_character_conversions (void);
  96.  
  97.   bool all_numeric_conversions (void);
  98.  
  99. private:
  100.  
  101.   // Number of conversions specified by this format string, or -1 if
  102.   // invalid conversions have been found.
  103.   int nconv;
  104.  
  105.   // Index to current element;
  106.   int curr_idx;
  107.  
  108.   // List of format elements.
  109.   Array<scanf_format_elt*> list;
  110.  
  111.   // Temporary buffer.
  112.   ostrstream *buf;
  113.  
  114.   void add_elt_to_list (int width, bool discard, char type, char modifier,
  115.             int& num_elts);
  116.  
  117.   void process_conversion (const string& s, int& i, int n, int& width,
  118.                bool& discard, char& type, char& modifier,
  119.                int& num_elts);
  120.  
  121.   int finish_conversion (const string& s, int& i, int n, int& width,
  122.              bool discard, char& type, char modifier,
  123.              int& num_elts);
  124.   // No copying!
  125.  
  126.   scanf_format_list (const scanf_format_list&);
  127.  
  128.   scanf_format_list& operator = (const scanf_format_list&);
  129. };
  130.  
  131. struct
  132. printf_format_elt
  133. {
  134.   printf_format_elt (const char *txt = 0, int n = 0, char typ = '\0',
  135.              char mod = '\0')
  136.     : text (txt), args (n), type (typ), modifier (mod) { }
  137.  
  138.   ~printf_format_elt (void) { delete text; }
  139.  
  140.   const char *text;
  141.   int args;
  142.   char type;
  143.   char modifier;
  144. };
  145.  
  146. class
  147. printf_format_list
  148. {
  149. public:
  150.  
  151.   printf_format_list (const string& fmt = string ());
  152.  
  153.   ~printf_format_list (void);
  154.  
  155.   int num_conversions (void) { return nconv; }
  156.  
  157.   const printf_format_elt *first (void)
  158.     {
  159.       curr_idx = 0;
  160.       return current ();
  161.     }
  162.  
  163.   const printf_format_elt *current (void) const
  164.     { return list.length () > 0 ? list.elem (curr_idx) : 0; }
  165.  
  166.   const printf_format_elt *next (void)
  167.     {
  168.       curr_idx++;
  169.       if (curr_idx >= list.length ())
  170.     curr_idx = 0;
  171.       return current ();
  172.     }
  173.  
  174.   void printme (void) const;
  175.  
  176.   bool ok (void) const { return (nconv >= 0); }
  177.  
  178.   operator void* () const { return ok () ? (void *) -1 : (void *) 0; }
  179.  
  180. private:
  181.  
  182.   // Number of conversions specified by this format string, or -1 if
  183.   // invalid conversions have been found.
  184.   int nconv;
  185.  
  186.   // Index to current element;
  187.   int curr_idx;
  188.  
  189.   // List of format elements.
  190.   Array<printf_format_elt*> list;
  191.  
  192.   // Temporary buffer.
  193.   ostrstream *buf;
  194.  
  195.   void add_elt_to_list (int args, char type, char modifier,
  196.             int& num_elts);
  197.  
  198.   void process_conversion (const string& s, int& i, int n, int& args,
  199.                char& modifier, char& type, int& num_elts);
  200.  
  201.   void finish_conversion (const string& s, int& i, int args,
  202.               char modifier, char& type, int& num_elts);
  203.  
  204.   // No copying!
  205.  
  206.   printf_format_list (const printf_format_list&);
  207.  
  208.   printf_format_list& operator = (const printf_format_list&);
  209. };
  210.  
  211. // Provide an interface for Octave streams.
  212.  
  213. class
  214. octave_base_stream
  215. {
  216. friend class octave_stream;
  217.  
  218. public:
  219.  
  220.   octave_base_stream (ios::openmode arg_md = ios::in|ios::out,
  221.               oct_mach_info::float_format ff = oct_mach_info::native)
  222.     : md (arg_md), flt_fmt (ff), fail (false) { }
  223.  
  224.   virtual ~octave_base_stream (void) { }
  225.  
  226.   // The remaining functions are not specific to input or output only,
  227.   // and must be provided by the derived classes.
  228.  
  229.   // Position a stream at OFFSET relative to ORIGIN.
  230.  
  231.   virtual int seek (streamoff offset, ios::seek_dir origin) = 0;
  232.  
  233.   // Return current stream position.
  234.  
  235.   virtual long tell (void) const = 0;
  236.  
  237.   // Return non-zero if EOF has been reached on this stream.
  238.  
  239.   virtual bool eof (void) const = 0;
  240.  
  241.   // The name of the file.
  242.  
  243.   virtual string name (void) = 0;
  244.  
  245.   // If the derived class provides this function and it returns a
  246.   // pointer to a valid istream, scanf(), read(), getl(), and gets()
  247.   // will automatically work for this stream.
  248.  
  249.   virtual istream *input_stream (void) { return 0; }
  250.  
  251.   // If the derived class provides this function and it returns a
  252.   // pointer to a valid ostream, flush(), write(), and printf() will
  253.   // automatically work for this stream.
  254.  
  255.   virtual ostream *output_stream (void) { return 0; }
  256.  
  257.   bool ok (void) const { return ! fail; }
  258.  
  259.   // Return current error message for this stream.
  260.  
  261.   string error (bool clear, int& err_num);
  262.  
  263. protected:
  264.  
  265.   int mode (void) { return md; }
  266.  
  267.   oct_mach_info::float_format float_format (void) { return flt_fmt; }
  268.  
  269.   // Set current error state and set fail to TRUE.
  270.  
  271.   void error (const string& msg);
  272.  
  273.   // Clear any error message and set fail to FALSE.
  274.  
  275.   void clear (void);
  276.  
  277. private:
  278.  
  279.   // The permission bits for the file.  Should be some combination of
  280.   // ios::open_mode bits.
  281.   int md;
  282.  
  283.   // Data format.
  284.   oct_mach_info::float_format flt_fmt;
  285.  
  286.   // TRUE if an error has occurred.
  287.   bool fail;
  288.  
  289.   // Should contain error message if fail is TRUE.
  290.   string errmsg;
  291.  
  292.   // Functions that are defined for all input streams (input streams
  293.   // are those that define is).
  294.  
  295.   string do_gets (int max_len, bool& err, bool strip_newline,
  296.           const char *fcn);
  297.  
  298.   string getl (int max_len, bool& err);
  299.   string gets (int max_len, bool& err);
  300.  
  301.   octave_value do_read (int nr, int nc, oct_data_conv::data_type dt,
  302.             int skip, oct_mach_info::float_format flt_fmt,
  303.             int& count);
  304.  
  305.   octave_value read (const Matrix& size, oct_data_conv::data_type dt,
  306.              int skip, oct_mach_info::float_format flt_fmt,
  307.              int& count);
  308.  
  309.   octave_value do_char_scanf (scanf_format_list& fmt_list,
  310.                   int nr, int nc, int& count);
  311.  
  312.   octave_value do_real_scanf (scanf_format_list& fmt_list,
  313.                   int nr, int nc, int& count);
  314.  
  315.   octave_value do_scanf (scanf_format_list& fmt_list, int nr, int nc,
  316.              int& count);
  317.  
  318.   octave_value scanf (const string& fmt, const Matrix& size, int& count);
  319.  
  320.   bool do_oscanf (const scanf_format_elt *elt, octave_value&);
  321.  
  322.   octave_value_list oscanf (const string& fmt);
  323.  
  324.   // Functions that are defined for all output streams (output streams
  325.   // are those that define os).
  326.  
  327.   int flush (void);
  328.  
  329.   int do_write (const Matrix& m, oct_data_conv::data_type dt, int skip,
  330.         oct_mach_info::float_format flt_fmt);
  331.  
  332.   int write (const octave_value& data, oct_data_conv::data_type dt,
  333.          int skip, oct_mach_info::float_format flt_fmt);
  334.  
  335.   int do_printf (printf_format_list& fmt_list, const octave_value_list& args);
  336.  
  337.   int printf (const string& fmt, const octave_value_list& args);
  338.  
  339.   int puts (const string& s);
  340.  
  341.   // We can always do this in terms of seek(), so the derived class
  342.   // only has to provide that.
  343.  
  344.   int rewind (void);
  345.  
  346.   void invalid_operation (const char *op, const char *rw);
  347.  
  348.   // No copying!
  349.  
  350.   octave_base_stream (const octave_base_stream&);
  351.  
  352.   octave_base_stream& operator = (const octave_base_stream&);
  353. };
  354.  
  355. class
  356. octave_stream
  357. {
  358. public:
  359.  
  360.   octave_stream (octave_base_stream *bs = 0, bool pf = false)
  361.     : rep (bs), preserve (pf) { }
  362.  
  363.   ~octave_stream (void)
  364.     {
  365.       if (! preserve)
  366.     delete rep;
  367.     }
  368.  
  369.   int flush (void);
  370.  
  371.   string getl (int max_len, bool& err);
  372.   string getl (const octave_value& max_len, bool& err);
  373.  
  374.   string gets (int max_len, bool& err);
  375.   string gets (const octave_value& max_len, bool& err);
  376.  
  377.   int seek (streamoff offset, ios::seek_dir origin);
  378.   int seek (const octave_value& offset, const octave_value& origin);
  379.  
  380.   long tell (void) const;
  381.  
  382.   int rewind (void);
  383.  
  384.   octave_value read (const Matrix& size, oct_data_conv::data_type dt,
  385.              int skip, oct_mach_info::float_format flt_fmt,
  386.              int& count);
  387.  
  388.   int write (const octave_value& data, oct_data_conv::data_type dt,
  389.          int skip, oct_mach_info::float_format flt_fmt);
  390.  
  391.   octave_value scanf (const string& fmt, const Matrix& size, int& count);
  392.  
  393.   octave_value_list oscanf (const string& fmt);
  394.  
  395.   int printf (const string& fmt, const octave_value_list& args);
  396.  
  397.   int puts (const string& s);
  398.   int puts (const octave_value& s);
  399.  
  400.   bool eof (void) const;
  401.  
  402.   string error (bool clear, int& err_num);
  403.  
  404.   string error (bool clear = false)
  405.     {
  406.       int err_num;
  407.       return error (clear, err_num);
  408.     }
  409.  
  410.   bool ok (void) const { return rep && rep->ok (); }
  411.  
  412.   operator void* () const { return ok () ? (void *) -1 : (void *) 0; }
  413.  
  414.   string name (void);
  415.  
  416.   int mode (void);
  417.  
  418.   oct_mach_info::float_format float_format (void);
  419.  
  420.   static string mode_as_string (int mode);
  421.  
  422. private:
  423.  
  424.   // The actual representation of this stream.
  425.   octave_base_stream *rep;
  426.  
  427.   // If true, do not delete rep.
  428.   bool preserve;
  429.  
  430.   void invalid_stream_error (const char *op) const;
  431.  
  432.   bool stream_ok (const char *op, bool clear = true) const
  433.     {
  434.       bool retval = true;
  435.  
  436.       if (rep)
  437.     {
  438.       if (clear)
  439.         rep->clear ();
  440.     }
  441.       else
  442.     {
  443.       retval = false;
  444.       invalid_stream_error (op);
  445.     }
  446.  
  447.       return retval;
  448.     }
  449.  
  450.   void error (const string& msg)
  451.     {
  452.       if (rep)
  453.     rep->error (msg);
  454.     }
  455.  
  456.   // Must create named streams.
  457.  
  458.   octave_stream (void);
  459.  
  460.   // No copying!
  461.  
  462.   octave_stream (const octave_stream&);
  463.  
  464.   octave_stream& operator = (const octave_stream&);
  465. };
  466.  
  467. class
  468. octave_stream_list
  469. {
  470. protected:
  471.  
  472.   octave_stream_list (void) : list (32), curr_len (0) { }
  473.  
  474. public:
  475.  
  476.   ~octave_stream_list (void) { }
  477.  
  478.   static int insert (octave_base_stream *obs);
  479.  
  480.   static octave_stream *lookup (int fid);
  481.   static octave_stream *lookup (const octave_value& fid);
  482.  
  483.   static int remove (int fid);
  484.   static int remove (const octave_value& fid);
  485.  
  486.   static void clear (void);
  487.  
  488.   static string_vector get_info (int fid);
  489.   static string_vector get_info (const octave_value& fid);
  490.  
  491.   static string list_open_files (void);
  492.  
  493.   static octave_value open_file_numbers (void);
  494.  
  495.   static int get_file_number (const octave_value& fid);
  496.  
  497. private:
  498.  
  499.   Array<octave_stream*> list;
  500.  
  501.   int curr_len;
  502.  
  503.   static octave_stream_list *instance;
  504.  
  505.   int do_insert (octave_base_stream *obs);
  506.  
  507.   octave_stream *do_lookup (int fid) const;
  508.   octave_stream *do_lookup (const octave_value& fid) const;
  509.  
  510.   int do_remove (int fid);
  511.   int do_remove (const octave_value& fid);
  512.  
  513.   void do_clear (void);
  514.  
  515.   string_vector do_get_info (int fid) const;
  516.   string_vector do_get_info (const octave_value& fid) const;
  517.  
  518.   string do_list_open_files (void) const;
  519.  
  520.   octave_value do_open_file_numbers (void) const;
  521.  
  522.   int do_get_file_number (const octave_value& fid) const;
  523. };
  524.  
  525. #endif
  526.  
  527. /*
  528. ;;; Local Variables: ***
  529. ;;; mode: C++ ***
  530. ;;; End: ***
  531. */
  532.